package api.utils;

import api.HttpResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.AbstractHttpMessage;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;

import static api.utils.StringToMapUtils.convert1;
import static api.utils.StringToMapUtils.convert2;

//冗余
@Slf4j
public class HttpClientUtils {

    public static HttpResult doPost(String url) {
        return doPost(url, "", "");
    }

    public static HttpResult doPost(String url, String parmams) {
        return doPost(url, parmams, "");
    }


    //method=loginMobile&loginname=abc&loginpass=abc
    //token=61b3590090982a0185dda9d3bd793b46;userId=123
    public static HttpResult doPost(String url, String parmams, String headers) {
        return doPostMap(url,convert1(parmams),convert2(headers));
    }


    //获取 返回结果 头部信息 获取返回结果状态码
    //token=61b3590090982a0185dda9d3bd793b46;userId=123 -> map 转换
    public static HttpResult doPostMap(String url, Map<String,Object> parmams, Map<String,Object> headers) {

        CloseableHttpClient httpClient = getHttpClient();
        HttpPost httpPost = new HttpPost(url);
        HttpEntity entity = null;
        HttpResult httpResult = new HttpResult();
        try {
            if(MapUtils.isNotEmpty(parmams)){
                ArrayList<BasicNameValuePair> parameters = new ArrayList<>();
                parmams.forEach((k,v)->parameters.add(new BasicNameValuePair(k, String.valueOf(v))));
                httpPost.setEntity(new UrlEncodedFormEntity(parameters));
            }
            if(MapUtils.isNotEmpty(headers)){
                headers.forEach((k,v)->httpPost.addHeader(k,String.valueOf(v)));
            }

            CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
            int statusCode = httpResponse.getStatusLine().getStatusCode();


            entity = httpResponse.getEntity();
           // getCookie(apiHttpClient.getCookieStore());
            String msg = EntityUtils.toString(entity, "utf-8");
            httpResult.setMsg(msg);
            httpResult.setHeaders(httpResponse.getAllHeaders());
            httpResult.setCode(statusCode);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                EntityUtils.consume(entity);
            } catch (IOException e) {
                log.error("error {}",e.getMessage());
               // e.printStackTrace();
            }
        }
        return httpResult;
    }
    public static  boolean openProxy=false;



    private static ApiCloseableHttpClient getHttpClientAndCookie() {
        ApiCloseableHttpClient apiCloseableHttpClient=new ApiCloseableHttpClient();
        CookieStore cookieStore = new BasicCookieStore();
        CloseableHttpClient client;
        apiCloseableHttpClient.setCookieStore(cookieStore);
        if(openProxy){
            HttpHost proxy = new HttpHost("127.0.0.1", 8888, "http");

            RequestConfig defaultRequestConfig = RequestConfig.custom()
                    .setProxy(proxy)
                    .build();
            //实例化CloseableHttpClient对象
             client= HttpClients.custom().
                    setDefaultRequestConfig(defaultRequestConfig).
                    setDefaultCookieStore(cookieStore).
                    build();
        }else{
             client = HttpClients.custom().setDefaultCookieStore(cookieStore).
                    build();
        }
        apiCloseableHttpClient.setClient(client);
        return apiCloseableHttpClient;
    }

   static Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
            .register("http", PlainConnectionSocketFactory.INSTANCE).
            // trustAllHttpsCertificates 处理https
                    register("https", SslUtil.trustAllHttpsCertificates()).build();
    // 创建ConnectionManager，添加Connection配置信息
    static  PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(
            socketFactoryRegistry);

    private static CloseableHttpClient getHttpClient() {
      //  return SslUtil.SslHttpClientBuild(openProxy);
        CloseableHttpClient client;
        if(openProxy){
            HttpHost proxy = new HttpHost("127.0.0.1", 8888, "http");

            RequestConfig defaultRequestConfig = RequestConfig.custom()
                    .setProxy(proxy)
                    .build();
            //实例化CloseableHttpClient对象
            client= HttpClients.custom().setConnectionManager(connectionManager).
                    setDefaultRequestConfig(defaultRequestConfig).
                    build();

        }else{
            client = HttpClients.custom().setConnectionManager(connectionManager).build();
        }
        return  client;
    }


    private static CloseableHttpClient getHttpClient(CookieStore cookieStore) {
        if(openProxy){
            HttpHost proxy = new HttpHost("127.0.0.1", 8888, "http");

            RequestConfig defaultRequestConfig = RequestConfig.custom()
                    .setProxy(proxy)
                    .build();
            //实例化CloseableHttpClient对象
            return HttpClients.custom().
                    setDefaultRequestConfig(defaultRequestConfig).
                    setConnectionManager(connectionManager)
                    .setDefaultCookieStore(cookieStore).
                    build();
        }else{
            return  HttpClients.custom().setConnectionManager(connectionManager).setDefaultCookieStore(cookieStore).
                    build();
        }
    }

    /**
     * @param url
     * @return
     */
    public static HttpResult doGet(String url) {
        return doGet(url, "");
    }

    /**
     * get请求
     *
     * @param url
     * @param headers //token=61b3590090982a0185dda9d3bd793b46;userId=123
     * @return
     */
    public static HttpResult doGet(String url, String headers) {
        return doGetMap(url,convert2(headers));
    }

    public HttpResult doPut(String url, Map<String, String> headerMap,String requestBody) {
        String entityStr = null;
        CloseableHttpResponse response = null;
        CloseableHttpClient httpClient = getHttpClient();
        HttpEntity httpEntity = null;
        HttpResult httpResult = new HttpResult();
        try {
            HttpPut post = new HttpPut(url);
            //添加头部信息
            for (Map.Entry<String, String> header : headerMap.entrySet()) {
                post.addHeader(header.getKey(), header.getValue());
            }
            HttpEntity entity = new StringEntity(requestBody,"Utf-8");
            System.out.println("请求体是："+requestBody);
            post.setEntity(entity);
            response = httpClient.execute(post);
            // 获得响应的实体对象
             httpEntity = response.getEntity();
            // 使用Apache提供的工具类进行转换成字符串
            entityStr = EntityUtils.toString(httpEntity, "UTF-8");
            System.out.println("PUT请求路径："+post);
            System.out.println("PUT请求结果："+entityStr);
            httpResult.setMsg(entityStr);
            httpResult.setHeaders(response.getAllHeaders());
            httpResult.setCode(response.getStatusLine().getStatusCode());
        } catch (Exception e) {

        }finally {
            try{
                EntityUtils.consume(httpEntity);
            }catch (Exception ex){

            }
        }
        return httpResult;
    }

    //https://www.cjavapy.com/article/537/
    public static HttpResult doGetMap(String url, Map<String,Object> headers,CookieStore cookieStore) {
        CloseableHttpClient httpClient = getHttpClient();

        CloseableHttpResponse httpResponse = null;
        HttpResult httpResult = new HttpResult();
        HttpEntity entity = null;
        try {
            HttpGet httpGet = new HttpGet(url);
            if(MapUtils.isNotEmpty(headers)){
                headers.forEach((k,v)->httpGet.addHeader(k, String.valueOf(v)));
            }
            httpResponse = httpClient.execute(httpGet);
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            entity = httpResponse.getEntity();
            String msg= EntityUtils.toString(entity, "utf-8");
            httpResult.setMsg(msg);
            httpResult.setHeaders(httpResponse.getAllHeaders());
            httpResult.setCode(statusCode);
        } catch (IOException e) {
            e.printStackTrace();
            httpResult.setCode(500);
        } finally {
            try {
                EntityUtils.consume(entity);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return httpResult;

    }


    public static HttpResult doDeletedMap(String url, Map<String,Object> headers) {
        CloseableHttpClient httpClient = getHttpClient();

        CloseableHttpResponse httpResponse = null;
        HttpResult httpResult = new HttpResult();
        HttpEntity entity = null;
        try {
            HttpDelete httpDelete = new HttpDelete(url);
            if(MapUtils.isNotEmpty(headers)){
                headers.forEach((k,v)->httpDelete.addHeader(k, String.valueOf(v)));
            }
            httpResponse = httpClient.execute(httpDelete);
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            entity = httpResponse.getEntity();
            String msg= EntityUtils.toString(entity, "utf-8");
            httpResult.setMsg(msg);
            httpResult.setHeaders(httpResponse.getAllHeaders());
            httpResult.setCode(statusCode);
        } catch (IOException e) {
            e.printStackTrace();
            httpResult.setCode(500);
        } finally {
            try {
                EntityUtils.consume(entity);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return httpResult;
    }

    public static HttpResult doGetMap(String url, Map<String,Object> headers) {

        CookieStore cookieStore=new BasicCookieStore();
        CloseableHttpClient httpClient = getHttpClient();

        CloseableHttpResponse httpResponse = null;
        HttpResult httpResult = new HttpResult();
        HttpEntity entity = null;
        try {
            HttpGet httpGet = new HttpGet(url);

            if(MapUtils.isNotEmpty(headers)){
                headers.forEach((k,v)->httpGet.addHeader(k, String.valueOf(v)));
            }
            httpResponse = httpClient.execute(httpGet);
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            entity = httpResponse.getEntity();
            getCookie(cookieStore);
            String msg= EntityUtils.toString(entity, "utf-8");
            httpResult.setMsg(msg);
            httpResult.setHeaders(httpResponse.getAllHeaders());
            httpResult.setCode(statusCode);
        } catch (Exception e) {
            e.printStackTrace();
            httpResult.setCode(500);
        } finally {
            try {
                EntityUtils.consume(entity);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return httpResult;
    }

    public static HttpResult doPostJson(String url, String json) {
        return doPostJson(url, json, "");
    }

    public static HttpResult doPostJson(String url, String json, String headers) {
         return doPostJsonMap(url,json,convert2(headers));

    }

    public static HttpResult doPostJsonMap(String url, String json, Map<String,Object> headers) {
        CloseableHttpClient httpClient = getHttpClient();
        HttpPost httpPost = new HttpPost(url);
        HttpEntity entity = null;
        HttpResult httpResult = new HttpResult();
        try {
            if (StringUtils.isNotBlank(json)) {
                StringEntity str = new StringEntity(json, "utf-8");
                httpPost.setEntity(str);
            }
            //setHeaders(headers, httpPost);
            if(MapUtils.isNotEmpty(headers)){
                headers.forEach((k,v)->httpPost.addHeader(k, String.valueOf(v)));
            }

            httpPost.setHeader("Content-type", "application/json");
            // httpPost.setHeader("Content-type", "application/xml");
            CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            entity = httpResponse.getEntity();
           // getCookie(apiHttpClient.getCookieStore());
            String msg = EntityUtils.toString(entity, "utf-8");
            httpResult.setMsg(msg);
            httpResult.setHeaders(httpResponse.getAllHeaders());
            httpResult.setCode(statusCode);
        } catch (Exception e) {
            e.printStackTrace();
            httpResult.setCode(500);
        } finally {
            try {
                EntityUtils.consume(entity);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


        return httpResult;
    }

    private static void getCookie(CookieStore cookieStore){
        List<Cookie> cookies = cookieStore.getCookies();
        for (int i = 0; i < cookies.size(); i++) {
            //遍历Cookies
            System.out.println(cookies.get(i));
            System.out.println("cookiename=="+cookies.get(i).getName());
            System.out.println("cookieValue=="+cookies.get(i).getValue());
            System.out.println("Domain=="+cookies.get(i).getDomain());
            System.out.println("Path=="+cookies.get(i).getPath());
            System.out.println("Version=="+cookies.get(i).getVersion());
//
//            if (cookies.get(i).getName().equals("JSESSIONID")) {
//                JSESSIONID = cookies.get(i).getValue();
//            }
//            if (cookies.get(i).getName().equals("cookie_user")) {
//                cookie_user = cookies.get(i).getValue();
//            }
        }
    }


}
